﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "GStyleViewerUtils.h"
#include "IUiView.h"
#include "IElement.h"
#include "IDocument.h"
#include "ElementId.h"
#include "ICategory.h"
#include "IModelView.h"
#include "IUiDocument.h"
#include "UniIdentity.h"
#include "IDirectShape.h"
#include "IFillPattern.h"
#include "IGraphicsNode.h"
#include "IGraphicsStyle.h"
#include "IGenericElement.h"
#include "ICategoryLibrary.h"
#include "IFillPatternData.h"
#include "IElementModelShape.h"
#include "UiDocumentViewUtils.h"
#include "IGraphicsElementShape.h"
#include "IGraphicsStyleManager.h"
#include "IGraphicsNodeReference.h"
#include "IElementBasicInformation.h"
#include "IGraphicsStyleDataOverrideItems.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "IElementViewSpecificShapeComponent.h"
#include "IGraphicsNodeStyleAndMaterialOverride.h"
#include "IGraphicsNodeStyleAndMaterialCustomizer.h"

#include "GRepModule.h"
#include "GRepCommandIds.h"
#include "CommandRegister.h"
#include "CustomizerGStyleManager.h"
#include "CmdGStyleModuleEntry.h"
#include "SampleGraphicsNodeStyleCustomizer.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 

using namespace gcmp;
using namespace Sample;

#pragma region 初始化和主要的获取设置显示样式数据入口

GStyleViewerUtils::GStyleViewerUtils(IUiView* pCurrentView, ElementId elemId, const IGraphicsNode* gNode)
    : m_pUiView(pCurrentView)
    , m_elemId(elemId)
    , m_pGNode(gNode)
{
    IUiDocument* pUIDoc = pCurrentView->GetUiDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc, L"pUIDoc为空",L"GDMP",L"2024-03-30");
    m_pDocument = pUIDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDocument, L"pDoc为空",L"GDMP",L"2024-03-30");
    DBG_WARN_AND_RETURN_VOID_UNLESS(GetElement(), L"GetElement()为空",L"GDMP",L"2024-03-30");
    const IElementBasicInformation* pElemBasicInfo = GetElement()->GetBasicInformation();
    m_categoryId = pElemBasicInfo->GetCategoryUid();
}

std::vector<OwnerPtr<GraphicsOverrideData>> GStyleViewerUtils::GetGStyles(bool canGNodeSetDirectly)
{
    std::vector<OwnerPtr<GraphicsOverrideData>> gOverrideDataList;
    IModelView* pModelView = m_pUiView->GetModelView();
    DBG_WARN_AND_RETURN_UNLESS(pModelView, gOverrideDataList, L"pModelView为空",L"GDMP",L"2024-03-30");
    IGraphicsStyleManager* pGStyleManager = m_pDocument->GetGraphicsStyleManager();
    DBG_WARN_AND_RETURN_UNLESS(pGStyleManager, gOverrideDataList, L"pGStyleManager 为空",L"GDMP",L"2024-03-30");

    IGraphicsStyle* pDocCategoryGStyle;
    // 文档类别级（IGraphicsStyleManager::GetGraphicsStyleIdByCategoryUid）
    {
        ElementId docCategoryGStyleId = pGStyleManager->GetGraphicsStyleIdByCategoryUid(m_categoryId);
        pDocCategoryGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(docCategoryGStyleId));
        DBG_WARN_AND_RETURN_UNLESS(pDocCategoryGStyle, gOverrideDataList, L"pDocGStyle为空",L"GDMP",L"2024-03-30");
        OwnerPtr<GraphicsOverrideData> opOverrideData = NEW_AS_OWNER_PTR(GraphicsOverrideData, TransferOwnership(pDocCategoryGStyle->GetGraphicsStyleData()));
        opOverrideData->m_gStyleId = docCategoryGStyleId;
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 视图类别级（IModelView::GetGraphicsStyleOverrideByCategoryUid）
    {
        std::pair<OwnerPtr<IGraphicsStyleDataOverrideItems>, OwnerPtr<IGraphicsStyleData>> overridePair =
            pModelView->GetGraphicsStyleOverrideByCategoryUid(m_categoryId);
        OwnerPtr<GraphicsOverrideData> opOverrideData = NEW_AS_OWNER_PTR(GraphicsOverrideData, TransferOwnership(overridePair.second));
        opOverrideData->m_opGStyleDataOverrideItems = TransferOwnership(overridePair.first);
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 文档级图元：回调
    //（IElement::GetShapeGraphicsNodeStyleAndMaterialOverrideComponent和IGraphicsNodeStyleAndMaterialOverride::GetGraphicsNodeStyleAndMaterialCustomizer）
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData = NEW_AS_OWNER_PTR(GraphicsOverrideData);
        // 不是所有图元都用IGraphicsNodeStyleAndMaterialOverride
        const IGraphicsNodeStyleAndMaterialOverride* pGNodeStyleOverride = GetElement()->GetShapeGraphicsNodeStyleAndMaterialOverrideComponent();
        if (!pGNodeStyleOverride)
        {
            opOverrideData->m_available = false;
        }
        else
        {
            const IGraphicsNodeStyleAndMaterialCustomizer* pGStyleCustomizer = pGNodeStyleOverride->GetGraphicsNodeStyleAndMaterialCustomizer();
            if (nullptr != pGStyleCustomizer)
            {
                IGraphicsNodeStyleAndMaterialCustomizer::CustomizationInfo customizationInfo = pGStyleCustomizer->GetCustomizationInfo(pModelView);
                std::vector<ElementId> gStyleIds;
                bool isCustomized = false;
                customizationInfo.GetCustomizedElementGraphicsStyle(GraphicsStyleOverrideGrade::Document, GraphicsStyleActiveRange::Background, isCustomized, gStyleIds);
                if (isCustomized && gStyleIds.size() > 0)
                {
                    // GDMP的一层样式重载可以按顺序重载多个IGraphicsStyle，示例程序仅支持一个
                    IGraphicsStyle* pOverrideGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(gStyleIds.at(0)));
                    if (pOverrideGStyle)
                    {
                        opOverrideData->m_opGStyleData = pOverrideGStyle->GetGraphicsStyleData();
                        opOverrideData->m_opGStyleDataValiditySettings = pOverrideGStyle->GetGraphicsStyleData()->GetDataValiditySettings();
                        opOverrideData->m_gStyleId = pOverrideGStyle->GetElementId();
                    }
                }
            }
            // 如果可以重载，但是没有重载
            if (nullptr == opOverrideData->m_opGStyleData)
            {
                // 图元显示样式数据用当前图元类别的显示样式作为初始值
                opOverrideData->m_opGStyleData = pDocCategoryGStyle->GetGraphicsStyleData();
                opOverrideData->m_opGStyleDataValiditySettings = IGraphicsStyleDataValiditySettings::Create();
                opOverrideData->m_opGStyleDataValiditySettings->ValidateNone();
            }
        }
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 视图级图元：回调
    //（IElement::GetShapeGraphicsNodeStyleAndMaterialOverrideComponent和IGraphicsNodeStyleAndMaterialOverride::GetGraphicsNodeStyleAndMaterialCustomizer）
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData = NEW_AS_OWNER_PTR(GraphicsOverrideData);
        const IGraphicsNodeStyleAndMaterialOverride* pGNodeStyleOverride = GetElement()->GetShapeGraphicsNodeStyleAndMaterialOverrideComponent();
        // 不是所有图元都用IGraphicsNodeStyleAndMaterialOverride
        if (!pGNodeStyleOverride)
        {
            opOverrideData->m_available = false;
        }
        else
        {
            const IGraphicsNodeStyleAndMaterialCustomizer* pGStyleCustomizer = pGNodeStyleOverride->GetGraphicsNodeStyleAndMaterialCustomizer();

            if (nullptr != pGStyleCustomizer)
            {
                IGraphicsNodeStyleAndMaterialCustomizer::CustomizationInfo customizationInfo = pGStyleCustomizer->GetCustomizationInfo(pModelView);
                std::vector<ElementId> gStyleIds;
                bool isCustomized = false;
                customizationInfo.GetCustomizedElementGraphicsStyle(GraphicsStyleOverrideGrade::ModelView, GraphicsStyleActiveRange::Background, isCustomized, gStyleIds);
                if (isCustomized && gStyleIds.size() > 0)
                {
                    IGraphicsStyle* pOverrideGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(gStyleIds.at(0)));
                    if (pOverrideGStyle)
                    {
                        opOverrideData->m_opGStyleData = pOverrideGStyle->GetGraphicsStyleData();
                        opOverrideData->m_opGStyleDataValiditySettings = pOverrideGStyle->GetGraphicsStyleData()->GetDataValiditySettings();
                        opOverrideData->m_gStyleId = pOverrideGStyle->GetElementId();
                    }
                }
            }
            // 如果可以重载，但是没有重载
            if (nullptr == opOverrideData->m_opGStyleData)
            {
                // 图元显示样式数据用当前图元类别的显示样式作为初始值
                opOverrideData->m_opGStyleData = pDocCategoryGStyle->GetGraphicsStyleData();
                opOverrideData->m_opGStyleDataValiditySettings = IGraphicsStyleDataValiditySettings::Create();
                opOverrideData->m_opGStyleDataValiditySettings->ValidateNone();
            }
        }
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 文档级节点：回调GStyleName
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData =
            GetCustomizerData(GraphicsStyleOverrideGrade::Document, GNodeGStyleOverrideType::ByGraphicsStyleName);
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 文档级节点：回调GStyleCategory
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData =
            GetCustomizerData(GraphicsStyleOverrideGrade::Document, GNodeGStyleOverrideType::ByGraphicsStyleCategory);
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 视图级节点：回调GStyleName
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData =
            GetCustomizerData(GraphicsStyleOverrideGrade::ModelView, GNodeGStyleOverrideType::ByGraphicsStyleName);
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 视图级节点：回调GStyleCategory
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData =
            GetCustomizerData(GraphicsStyleOverrideGrade::ModelView, GNodeGStyleOverrideType::ByGraphicsStyleCategory);
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    // 节点直接设置
    {
        OwnerPtr<GraphicsOverrideData> opOverrideData = NEW_AS_OWNER_PTR(GraphicsOverrideData);
        ElementId gNodeGStyleId = m_pGNode->GetGraphicsStyleId();
        IGraphicsStyle* pGNodeGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(gNodeGStyleId));
        opOverrideData->m_available = canGNodeSetDirectly;
        // 如果节点有显示样式
        if (pGNodeGStyle)
        {
            opOverrideData->m_opGStyleData = pGNodeGStyle->GetGraphicsStyleData();
            opOverrideData->m_opGStyleDataValiditySettings = opOverrideData->m_opGStyleData->GetDataValiditySettings();
            const IElementBasicInformation* pElementBasicInfo = pGNodeGStyle->GetBasicInformation();
            opOverrideData->m_gNodeText = pElementBasicInfo->GetName();
            ICategoryLibrary* pCategoryLib = ICategoryLibrary::Get(m_pDocument);
            opOverrideData->m_gNodeCategory = pCategoryLib->GetCategory(pGNodeGStyle->GetTargetCategoryUid());
            opOverrideData->m_gStyleId = pGNodeGStyle->GetElementId();
        }
        else
        {
            // 如果节点没有显示样式，则使用图元类别的文档级显示样式作为初始值
            opOverrideData->m_opGStyleData = pDocCategoryGStyle->GetGraphicsStyleData();
            opOverrideData->m_opGStyleDataValiditySettings = IGraphicsStyleDataValiditySettings::Create();
            opOverrideData->m_opGStyleDataValiditySettings->ValidateNone();
        }
        opOverrideData->m_hasGNodeText = true;
        gOverrideDataList.push_back(TransferOwnership(opOverrideData));
    }
    return TransferOwnership(gOverrideDataList);
}

void GStyleViewerUtils::SetGStyles(std::vector<OwnerPtr<GraphicsOverrideData>> gOverrideDataList, bool canGNodeSetDirectly, OwnerPtr<IGraphicsElementShape> opCachedGRep)
{
    IModelView* pModelView = m_pUiView->GetModelView();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pModelView, L"pModelView为空",L"GDMP",L"2024-03-30");
    IGraphicsStyleManager* pGStyleManager = m_pDocument->GetGraphicsStyleManager();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pGStyleManager, L"pGStyleManager 为空",L"GDMP",L"2024-03-30");
    IDocument* pDocument = pModelView->GetDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDocument, L"pDocument 为空",L"GDMP",L"2024-03-30");

    CustomizerGStyleManager* pCustomGStyleManager = CustomizerGStyleManager::Get(pDocument);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCustomGStyleManager, L"pCustomGStyleManager为空",L"GDMP",L"2024-03-30");
    ElementId elemId = GetElement()->GetElementId();
    ElementId viewId = pModelView->GetElementId();
    bool isCustomized = false;
    int index = 0;
    // 文档类别级：IGraphicsStyleManager::GetGraphicsStyleIdByCategoryUid
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        ElementId styleId = pGStyleManager->GetGraphicsStyleIdByCategoryUid(m_categoryId);
        IGraphicsStyle* pDocCategoryGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(styleId));
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDocCategoryGStyle, L"pDocGStyle为空",L"GDMP",L"2024-03-30");
        pDocCategoryGStyle->SetGraphicsStyleData(*opOverrideData->m_opGStyleData);
    }
    // 视图类别级：IModelView::OverrideGraphicsStyleByCategoryUid
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        pModelView->OverrideGraphicsStyleByCategoryUid(m_categoryId, *opOverrideData->m_opGStyleDataOverrideItems, *opOverrideData->m_opGStyleData);
    }
    // 文档级图元：回调
    // SampleGraphicsNodeStyleAndMaterialCustomizer不能存储数据；样式重载数据都存在CustomizerGStyleManager，因此直接修改CustomizerGStyleManager
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        IGraphicsStyle* pOverrideGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(opOverrideData->m_gStyleId));
        // 两种情况更新样式重载数据：1-样式可以重载，并且样式有效性有设置；之前就有显示样式（这时可能将有效性设置全设为空）
        if (opOverrideData->m_available && (!opOverrideData->m_opGStyleDataValiditySettings->IsNoneValid() || pOverrideGStyle))
        {
            if (!pOverrideGStyle)
            {
                // 没有样式则创建一个
                pOverrideGStyle = IGraphicsStyle::Create(m_pDocument, ElementCreationOptions::Normal);
                pOverrideGStyle->SetOwnerId(elemId);
            }
            opOverrideData->m_opGStyleData->SetDataValiditySettings(*opOverrideData->m_opGStyleDataValiditySettings);
            pOverrideGStyle->SetGraphicsStyleData(*opOverrideData->m_opGStyleData);
            pCustomGStyleManager->UpdateElementGStyle(elemId, pOverrideGStyle->GetElementId());
            isCustomized = true;
        }
    }
    // 视图级图元：回调
    // SampleGraphicsNodeStyleAndMaterialCustomizer不能存储数据；样式重载数据都存在CustomizerGStyleManager，因此直接修改CustomizerGStyleManager
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        IGraphicsStyle* pOverrideGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(opOverrideData->m_gStyleId));
        // 两种情况更新样式重载数据：1-样式可以重载，并且样式有效性有设置；之前就有显示样式（这时可能将有效性设置全设为空）
        if (opOverrideData->m_available && (!opOverrideData->m_opGStyleDataValiditySettings->IsNoneValid() || pOverrideGStyle))
        {
            if (!pOverrideGStyle)
            {
                // 没有样式则创建一个
                pOverrideGStyle = IGraphicsStyle::Create(m_pDocument, ElementCreationOptions::Normal);
                pOverrideGStyle->SetOwnerId(elemId);
            }
            opOverrideData->m_opGStyleData->SetDataValiditySettings(*opOverrideData->m_opGStyleDataValiditySettings);
            pOverrideGStyle->SetGraphicsStyleData(*opOverrideData->m_opGStyleData);
            pCustomGStyleManager->UpdateViewElementGStyle(elemId, viewId, pOverrideGStyle->GetElementId());
            isCustomized = true;
        }
    }
    // 文档级节点：回调GStyle
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        if (SetCustomizerData(opOverrideData, GNodeGStyleOverrideType::ByGraphicsStyleName, GraphicsStyleOverrideGrade::Document))
        {
            isCustomized = true;
        }
    }
    // 文档级节点：回调Category
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        if (SetCustomizerData(opOverrideData, GNodeGStyleOverrideType::ByGraphicsStyleCategory, GraphicsStyleOverrideGrade::Document))
        {
            isCustomized = true;
        }
    }
    // 视图级节点：回调GStyle
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        if (SetCustomizerData(opOverrideData, GNodeGStyleOverrideType::ByGraphicsStyleName, GraphicsStyleOverrideGrade::ModelView))
        {
            isCustomized = true;
        }
    }
    // 视图级节点：回调Category
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        if (SetCustomizerData(opOverrideData, GNodeGStyleOverrideType::ByGraphicsStyleCategory, GraphicsStyleOverrideGrade::ModelView))
        {
            isCustomized = true;
        }
    }
    // 节点直接设置
    index++;
    {
        OwnerPtr<GraphicsOverrideData>& opOverrideData = gOverrideDataList.at(index);
        DBG_WARN_AND_RETURN_VOID_UNLESS(opOverrideData, L"opOverrideData为空",L"GDMP",L"2024-03-30");
        bool hasValiditySettings = !opOverrideData->m_opGStyleDataValiditySettings->IsNoneValid();
        IGraphicsStyle* pGNodeGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(opOverrideData->m_gStyleId));
        // 如果有有效性设置，或者原本节点就有样式；并且可以直接设置图形节点的显示样式（例如GRep探针浏览器中的图形节点是复制缓存的，只有特定图元可以设置）
        if ((hasValiditySettings || pGNodeGStyle) && canGNodeSetDirectly)
        {
            if (!pGNodeGStyle)
            {
                pGNodeGStyle = IGraphicsStyle::Create(m_pDocument, ElementCreationOptions::Normal);
                pGNodeGStyle->SetOwnerId(elemId);
            }

            IElementBasicInformation* pElementBasicInfo = pGNodeGStyle->GetBasicInformation();
            pElementBasicInfo->SetName(opOverrideData->m_gNodeText);

            // 如果是类别样式，那么类别样式的各项设置需要都有效，否则平台有警告信息，无法显示正确
            if (opOverrideData->m_gNodeCategory)
            {
                opOverrideData->m_opGStyleDataValiditySettings->ValidateAll();
            }

            opOverrideData->m_opGStyleData->SetDataValiditySettings(*opOverrideData->m_opGStyleDataValiditySettings);
            pGNodeGStyle->SetGraphicsStyleData(*opOverrideData->m_opGStyleData);

            IElementModelShape* pElemModelShape = GetElement()->GetElementModelShape();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pElemModelShape, L"pElemModelShape为空",L"GDMP",L"2024-03-30");
            // 暂时通过hack的方式强行设置。对于有些图元和有些样式设置，这样会无效；会被图元自身计算器的设置覆盖
            IGraphicsNode* pGNode = const_cast<IGraphicsNode*>(m_pGNode);
            pGNode->SetGraphicsStyleId(pGNodeGStyle->GetElementId());

            if (opCachedGRep)
            {
                pElemModelShape->SetGraphicsElementShape(TransferOwnership(opCachedGRep));
            }
        }
    }
    if (isCustomized)
    {
        IGraphicsNodeStyleAndMaterialOverride* pGNodeStyleOverride = GetElement()->GetShapeGraphicsNodeStyleAndMaterialOverrideComponentFW();
        if (pGNodeStyleOverride)
        {
            // 从外部设置的SetGraphicsNodeStyleAndMaterialCustomizer可能被图元自身的其他设置覆盖
            OwnerPtr<SampleGraphicsNodeStyleAndMaterialCustomizer> opGNodeStyleCustomizer = NEW_AS_OWNER_PTR(SampleGraphicsNodeStyleAndMaterialCustomizer, GetElement());
            pGNodeStyleOverride->SetGraphicsNodeStyleAndMaterialCustomizer(TransferOwnership(opGNodeStyleCustomizer));
        }
    }
}
#pragma endregion

#pragma region 图元图形节点显示样式重载的获取和设置
OwnerPtr<GraphicsOverrideData> GStyleViewerUtils::GetCustomizerData(gcmp::GraphicsStyleOverrideGrade gStyleOverrideGrade, GNodeGStyleOverrideType overrideType)
{
    // 创建一个图形样式的自定义数据，用于和UI来回传递数据
    OwnerPtr<GraphicsOverrideData> opOverrideData = NEW_AS_OWNER_PTR(GraphicsOverrideData);
    const IGraphicsNodeStyleAndMaterialOverride* pGNodeStyleOverride = GetElement()->GetShapeGraphicsNodeStyleAndMaterialOverrideComponent();
    if (!pGNodeStyleOverride)
    {
        // 没有样式重载器
        opOverrideData->m_available = false;
        return TransferOwnership(opOverrideData);
    }

    // 获得图形节点上的显示样式，没有则不可重载
    ElementId gNodeGStyleId = m_pGNode->GetGraphicsStyleId();
    IGraphicsStyle* pGNodeGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(gNodeGStyleId));
    if (pGNodeGStyle == nullptr)
    {
        opOverrideData->m_available = false;
        return TransferOwnership(opOverrideData);
    }

    const IGraphicsNodeStyleAndMaterialCustomizer* pGStyleCustomizer = pGNodeStyleOverride->GetGraphicsNodeStyleAndMaterialCustomizer();
    if (nullptr != pGStyleCustomizer)
    {
        IGraphicsNodeStyleAndMaterialCustomizer::CustomizationInfo customizationInfo = pGStyleCustomizer->GetCustomizationInfo(m_pUiView->GetModelView());

        if (overrideType == GNodeGStyleOverrideType::ByGraphicsStyleName)
        {
            IElementBasicInformation* pIElementBasicInformation = pGNodeGStyle->GetBasicInformation();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pIElementBasicInformation, L"pIElementBasicInformation为空", L"GDMP", L"2024-03-30");
            std::wstring gNodeName = pIElementBasicInformation->GetName();
            // 一个图元的不同节点可以有不同显示样式和对应的重载
            const std::map<std::wstring, ElementId> gNodeOverrideMap =
                customizationInfo.GetCustomizedElementGraphicsStylesByStyleNames(gStyleOverrideGrade);
            // 按照当前节点样式的名称查找重载的样式ID
            const auto& iter = gNodeOverrideMap.find(gNodeName);
            if (iter != gNodeOverrideMap.end())
            {
                opOverrideData->m_gNodeText = iter->first;
                opOverrideData->m_hasGNodeText = true;
                opOverrideData->m_gStyleId = iter->second;
            }
        }
        else if (overrideType == GNodeGStyleOverrideType::ByGraphicsStyleCategory)
        {
            const std::map<UniIdentity, ElementId> gNodeOverrideMap =
                customizationInfo.GetCustomizedElementGraphicsStylesByTargetCategoryUids(gStyleOverrideGrade);
            // 一个图元的不同节点可以有不同显示样式和对应的重载
            UniIdentity gStyleTargetCategoryId = pGNodeGStyle->GetTargetCategoryUid();
            // 按照当前节点样式的类别查找重载的样式ID
            const auto& iter = gNodeOverrideMap.find(gStyleTargetCategoryId);
            if (iter != gNodeOverrideMap.end())
            {
                ICategoryLibrary* pCategoryLib = ICategoryLibrary::Get(m_pDocument);
                const ICategory* pCategory = pCategoryLib->GetCategory(gStyleTargetCategoryId);
                if (pCategory)
                {
                    opOverrideData->m_gNodeCategory = pCategory;
                    opOverrideData->m_hasGNodeCategory = true;
                    opOverrideData->m_gStyleId = iter->second;
                }
                else
                {
                    opOverrideData->m_available = false;
                }
            }
        }
        // 如果找到已有的图形节点的样式重载
        if (opOverrideData->m_gStyleId.IsValid())
        {
            IGraphicsStyle* pOverrideGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(opOverrideData->m_gStyleId));
            DBG_WARN_AND_RETURN_UNLESS(pOverrideGStyle, TransferOwnership(opOverrideData), L"pOverrideGStyle为空",L"GDMP",L"2024-03-30");
            opOverrideData->m_opGStyleData = pOverrideGStyle->GetGraphicsStyleData();
            opOverrideData->m_opGStyleDataValiditySettings = pOverrideGStyle->GetGraphicsStyleData()->GetDataValiditySettings();
            opOverrideData->m_gStyleId = pOverrideGStyle->GetElementId();
        }
    }
    // 如果没有找到已有的图形节点的样式重载，或者没有样式重载器
    if (nullptr == opOverrideData->m_opGStyleData)
    {
        opOverrideData->m_opGStyleData = pGNodeGStyle->GetGraphicsStyleData();
        opOverrideData->m_opGStyleDataValiditySettings = IGraphicsStyleDataValiditySettings::Create();
        opOverrideData->m_opGStyleDataValiditySettings->ValidateNone();
        if (overrideType == GNodeGStyleOverrideType::ByGraphicsStyleName)
        {
            // 自定义重载数据中当前图形节点显示样式的名称
            opOverrideData->m_gNodeText = pGNodeGStyle->GetBasicInformation()->GetName();
            if (opOverrideData->m_gNodeText != L"")
            {
                opOverrideData->m_hasGNodeText = true;
            }
            else
            {
                opOverrideData->m_available = false;
            }
        }
        else if (overrideType == GNodeGStyleOverrideType::ByGraphicsStyleCategory)
        {
            ICategoryLibrary* pCategoryLib = ICategoryLibrary::Get(m_pDocument);
            UniIdentity gStyleTargetCategoryId = pGNodeGStyle->GetTargetCategoryUid();
            const ICategory* pCategory = pCategoryLib->GetCategory(gStyleTargetCategoryId);
            if (pCategory)
            {
                // 自定义重载数据中当前图形节点显示样式的类别
                opOverrideData->m_gNodeCategory = pCategory;
                opOverrideData->m_hasGNodeCategory = true;
            }
            else
            {
                // 如果图形节点的样式没有类别，那么按照类别做重载不可用
                opOverrideData->m_available = false;
            }
        }
    }

    return TransferOwnership(opOverrideData);
}

bool GStyleViewerUtils::SetCustomizerData(gcmp::OwnerPtr<GraphicsOverrideData>& opOverrideData, 
    GNodeGStyleOverrideType overrideType, gcmp::GraphicsStyleOverrideGrade gStyleOverrideGrade)
{
    IModelView* pModelView = m_pUiView->GetModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMP",L"2024-03-30");
    ElementId elemId = GetElement()->GetElementId();
    ElementId viewId = pModelView->GetElementId();

    ElementId gNodeGStyleId = m_pGNode->GetGraphicsStyleId();
    IGraphicsStyle* pGNodeGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(gNodeGStyleId));
    IGraphicsNodeStyleAndMaterialOverride* pGNodeStyleOverride = GetElement()->GetShapeGraphicsNodeStyleAndMaterialOverrideComponentFW();
    // 如果GetCustomizerData时就发现不可以重载，没有样式重载器，或者图形节点没有样式
    if (!opOverrideData->m_available || !pGNodeStyleOverride || !pGNodeGStyle)
    {
        return false;
    }

    IGraphicsStyle* pOverrideGStyle = quick_cast<IGraphicsStyle>(m_pDocument->GetElement(opOverrideData->m_gStyleId));
    // 如果原本图形节点就有重载的样式，或者样式重载有效性有设置
    if (!opOverrideData->m_opGStyleDataValiditySettings->IsNoneValid() || pOverrideGStyle)
    {
        // 如果没有重载的样式，则创建一个
        if (!pOverrideGStyle)
        {
            pOverrideGStyle = IGraphicsStyle::Create(m_pDocument, ElementCreationOptions::Normal);
            pOverrideGStyle->SetOwnerId(elemId);
        }
        opOverrideData->m_opGStyleData->SetDataValiditySettings(*opOverrideData->m_opGStyleDataValiditySettings);
        pOverrideGStyle->SetGraphicsStyleData(*opOverrideData->m_opGStyleData);

        // SampleGraphicsNodeStyleAndMaterialCustomizer不能存储数据；样式重载数据都存在CustomizerGStyleManager，因此直接修改CustomizerGStyleManager
        CustomizerGStyleManager* pCustomGStyleManager = CustomizerGStyleManager::Get(m_pDocument);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pCustomGStyleManager, L"pCustomGStyleManager为空", L"GDMP", L"2024-03-30");

        if (overrideType == GNodeGStyleOverrideType::ByGraphicsStyleName)
        {
            IElementBasicInformation* pIElementBasicInformation = pGNodeGStyle->GetBasicInformation();
            DBG_WARN_AND_RETURN_FALSE_UNLESS(pIElementBasicInformation, L"pIElementBasicInformation为空", L"GDMP", L"2024-03-30");
            std::wstring gNodeStyleName = pIElementBasicInformation->GetName();
            if (gStyleOverrideGrade == GraphicsStyleOverrideGrade::ModelView)
            {
                pCustomGStyleManager->UpdateViewGNodeNameGStyle(elemId, viewId, gNodeStyleName, pOverrideGStyle->GetElementId());
            }
            else
            {
                pCustomGStyleManager->UpdateGNodeNameGStyle(elemId, gNodeStyleName, pOverrideGStyle->GetElementId());
            }
            return true;
        }
        else if (overrideType == GNodeGStyleOverrideType::ByGraphicsStyleCategory)
        {
            UniIdentity gStyleCategoryId = pGNodeGStyle->GetTargetCategoryUid();
            if (gStyleOverrideGrade == GraphicsStyleOverrideGrade::ModelView)
            {
                pCustomGStyleManager->UpdateViewGNodeCategoryGStyle(elemId, viewId, gStyleCategoryId, pOverrideGStyle->GetElementId());
            }
            else
            {
                pCustomGStyleManager->UpdateGNodeCategoryGStyle(elemId, gStyleCategoryId, pOverrideGStyle->GetElementId());
            }
            return true;
        }
    }
    return false;
}
#pragma endregion

#pragma region 辅助函数
IElement * Sample::GStyleViewerUtils::GetElement()
{
    return m_pDocument->GetElement(m_elemId);
}

bool GStyleViewerUtils::CanCategoryHaveGraphicsMaterial(const IDocument* pDocument, const UniIdentity& categoryUid) const
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDocument, L"pDocument为空",L"GDMP",L"2024-03-30");

    // 得到类别
    const ICategoryLibrary* pCategoryLib = ICategoryLibrary::Get(const_cast<IDocument*>(pDocument));
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pCategoryLib, L"pCategoryLib为空",L"GDMP",L"2024-03-30");

    const ICategory* pCategory = pCategoryLib->GetCategory(categoryUid);
    if (pCategory == nullptr)
        return false;

    // 从类别中获取是否允许设置材质
    return pCategory->CanHaveGraphicsMaterial();
}

void Sample::GStyleViewerUtils::GetHatchPatternNames(gcmp::IDocument * pDoc, std::vector<std::wstring>& hatchPatternNames)
{
    std::vector<IElement*> HatchPatternElements = pDoc->GetElementsByCategory(BuiltInCategoryUniIdentities::BICU_HATCH_PATTERN);
    hatchPatternNames.push_back(L"");
    FOR_EACH(pHatchPatternElement, HatchPatternElements)
    {
        IGenericElement* pHatchPatternEle = quick_cast<IGenericElement>(pHatchPatternElement);
        if (!pHatchPatternEle)
            continue;

        DBG_WARN_AND_CONTINUE_UNLESS(pHatchPatternEle, L"pHatchPatternEle为空",L"GDMP",L"2024-03-30");
        IExternalObject* pExternalObject = pHatchPatternEle->GetExternalObject();
        DBG_WARN_AND_CONTINUE_UNLESS(pExternalObject, L"pExternalObject为空",L"GDMP",L"2024-03-30");
        IFillPattern* pHatchPatternElement = quick_cast<IFillPattern>(pExternalObject);
        DBG_WARN_AND_CONTINUE_UNLESS(pHatchPatternElement, L"pHatchPatternElement为空",L"GDMP",L"2024-03-30");
        const IFillPatternData* pHatchPattern = pHatchPatternElement->GetFillPatternData();
        DBG_WARN_AND_CONTINUE_UNLESS(pHatchPattern, L"pHatchPattern1为空",L"GDMP",L"2024-03-30");
        std::wstring name = pHatchPattern->GetName();
        hatchPatternNames.push_back(name);
    }
}
#pragma endregion

